﻿using System;
using System.Collections.Generic;
using System.Linq;
using Amazon.SimpleNotificationService.Model;
using NUnit.Framework;
using Rhino.Mocks;
using ShuttleBus.Transports.AmazonSqs;
using ShuttleBus.Transports.AmazonSqs.Clients;
using Tests.Transports.AmazonSqs.Fakes;

namespace Tests.Transports.AmazonSqs.SubscriptionRepositoryTests
{
    public partial class SubscriptionRepositoryTests
    {
        [TestFixture]
        public class WhenGettingSubscribers
        {
            private SnsSubscriptionRepository _repository;
            private ISnsClient _snsClient;

            [SetUp]
            public void SetUp()
            {
                _snsClient = MockRepository.GenerateMock<ISnsClient>();

                _repository = new SnsSubscriptionRepository(_snsClient, null, new Uri("sqs://my_queue"));
            }

            [TearDown]
            public void TearDown()
            {
                _snsClient.VerifyAllExpectations();
            }

            [Test]
            public void No_Subscriptions_Exist_Matching_This_Message_Type_Name()
            {
                _snsClient.Expect(s => s.QuerySubscriptions("MyMessage")).Return(new Subscription[0]);

                var results = _repository.GetSubscribersOf(new MyMessage());

                Assert.AreEqual(0, results.Count());
            }

            [Test]
            public void Single_Subscription_Exist_Matching_This_Message_Type_Name()
            {
                var subscriptions = new List<Subscription>
                                        {
                                            new Subscription
                                                {
                                                    Endpoint = "arn:aws:sqs:us-east-1:123456789012:some-endpoint",
                                                    Owner = "123456789012",
                                                    Protocol = "sqs",
                                                    SubscriptionArn = "arn:aws:sns:us-east-1:123456789012:some-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99",
                                                    TopicArn = "arn:aws:sns:us-east-1:162882392992:mymessage"
                                                }
                                        };

                _snsClient.Expect(s => s.QuerySubscriptions("MyMessage")).Return(subscriptions);

                var results = _repository.GetSubscribersOf(new MyMessage()).ToArray();

                Assert.AreEqual(1, results.Count());
                Assert.AreEqual(new Uri("sqs://some-endpoint"), results[0].Location);
                Assert.AreEqual(typeof(MyMessage).Name, results[0].Name);
                Assert.AreEqual(typeof(MyMessage).AssemblyQualifiedName, results[0].MessageType);
            }

            [Test]
            public void Multiple_Subscriptions_Exist_Matching_This_Message_Type_Name()
            {
                var subscriptions = new List<Subscription>
                                        {
                                            new Subscription
                                                {
                                                    Endpoint = "arn:aws:sqs:us-east-1:123456789012:some-endpoint",
                                                    Owner = "123456789012",
                                                    Protocol = "sqs",
                                                    SubscriptionArn =
                                                        "arn:aws:sns:us-east-1:123456789012:some-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99",
                                                    TopicArn = "arn:aws:sns:us-east-1:162882392992:mymessage"
                                                },
                                            new Subscription
                                                {
                                                    Endpoint = "arn:aws:sqs:us-east-1:123456789012:some-other-endpoint",
                                                    Owner = "123456789012",
                                                    Protocol = "sqs",
                                                    SubscriptionArn = "arn:aws:sns:us-east-1:123456789012:some-other-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99",
                                                    TopicArn = "arn:aws:sns:us-east-1:162882392992:mymessage"
                                                }
                                        };

                _snsClient.Expect(s => s.QuerySubscriptions("MyMessage")).Return(subscriptions);
                var results = _repository.GetSubscribersOf(new MyMessage()).ToArray();

                Assert.AreEqual(2, results.Count());

                Assert.AreEqual(new Uri("sqs://some-endpoint"), results[0].Location);
                Assert.AreEqual(typeof(MyMessage).Name, results[0].Name);
                Assert.AreEqual(typeof(MyMessage).AssemblyQualifiedName, results[0].MessageType);


                Assert.AreEqual(new Uri("sqs://some-other-endpoint"), results[1].Location);
                Assert.AreEqual(typeof(MyMessage).Name, results[1].Name);
                Assert.AreEqual(typeof(MyMessage).AssemblyQualifiedName, results[1].MessageType);
            }
        }
    }
}